#include "stdafx.h"

#include "NativeDepth.h"

NativeDepth::NativeDepth(void)
{
}
NativeDepth::~NativeDepth(void)
{
}

void NativeDepth::parseContour()
{
	ifstream ii("cont1.txt");
	ofstream oo("contour.txt");
	int n,m;
	double one;

	ii>>m;
	//oo<<m<<endl;

	for(int j=0;j<m;j++)
	{
		ii>>n;		
		oo<<n<<endl;

		for(int i=0;i<n;i++)
		{
			ii>>one;
			oo<<one<<endl;
			
			ii>>one;			
			oo<<one<<endl;	
		}
		
	}
	ii.close();
	oo.close();
	return;
}

void NativeDepth::parse()
{
	parseContour();
	ifstream ii("dp.txt");
	ofstream oo("dp1.txt");
	int n,m;
	double one;

	ii>>m;
	oo<<m<<endl;

	for(int j=0;j<m;j++)
	{
		ii>>n;
		numberOfPoints[j]=n;
		oo<<n<<endl;

		for(int i=0;i<n;i++)
		{
			ii>>one;
			oo<<one<<endl;
			
			P[j][i].x=one;
			ii>>one;
			
			oo<<one<<endl;	
			P[j][i].y=one;
		}
		//Get query point
			ii>>one;
			oo<<one<<endl;
			
			q[j].x=one;
			ii>>one;
			
			oo<<one<<endl;	
			q[j].y=one;
		
		//Get its depth
			ii>>one;
			Depth[j]=one;
			oo<<one<<endl;
	}
	ii.close();
	oo.close();
	return;
}
double NativeDepth::GetDirection()
{
	return did2;
}
double NativeDepth::GetXDirection()
{
	return P[pointSetID][did2].x;
}
double NativeDepth::GetYDirection()
{
	return P[pointSetID][did2].y;
}
double NativeDepth::GromovDepth(double qx, double qy)
{
	MyPoint q;
	q.x=qx;
	q.y=qy;
	return GromovDepth(q);
}
double NativeDepth::GromovDepth(MyPoint q)
{
	double angle[100];
	
	int total[100];
	
	int endOf[100];
	ofstream oo("dump.txt");

	//plot points on unit cicle around q and calculate angles
	for(int i=0;i<numberOfPoints[pointSetID];i++)
	{
		double slope ;
		if(q.y-P[pointSetID][i].y==0&&(q.x-P[pointSetID][i].x)==0)
			slope=0;
		else if ((q.x-P[pointSetID][i].x)==0)
			slope = 99999999999999999999.0;
		else
		slope = (q.y-P[pointSetID][i].y)/(q.x-P[pointSetID][i].x);
		angle[i]=atan(slope)*57.35;

		if (angle[i] < 0)   {
            angle[i] += 180;                
        }

        if (q.y > P[pointSetID][i].y) {
            angle[i] += 180;                 
        }	
		P[pointSetID][i].angle=angle[i];
	}

	//sort
	sort(angle,angle+numberOfPoints[pointSetID]);
	sort(P[pointSetID],P[pointSetID]+numberOfPoints[pointSetID]);


	//Fill array from number of points between a point and its antipodal
	
    int count = 0;//points in between 
    int index=0;//of points for which we have found antipodals
	for (int i = 0; index < numberOfPoints[pointSetID]  ; i++)
    {
		count++;
        if ( (i-index)>= numberOfPoints[pointSetID] ||angle[i % numberOfPoints[pointSetID] ] > (angle[index] + 180) ||
			
			((angle[i % numberOfPoints[pointSetID] ] < (angle[index]) && (angle[i % numberOfPoints[pointSetID] ] + 360 > (angle[index] + 180)))))
        
		{
			count--;
        
			total[index] = count - 1;
            endOf[index] = i - 1;
            index++;
            count--;
            i--;

        }
    }

	//calculate depth for first ray between 1 and n points.
	
    double minDepth = 100000;
    
	double ray[100];
    ray[0] = 0;
	did2=0;
	double current_angle=0,largest_angle = 0;
    for (int i = 0; i <= total[0]; i++)
		ray[0] += numberOfPoints[pointSetID] - ( (total[i])+ i +1);
    minDepth = ray[0];

	//change for oja depth and RS depth
	if(ray[0]>=1.0/8.0*numberOfPoints[pointSetID]*numberOfPoints[pointSetID])
	{
		oo<<"1"<<endl<<P[pointSetID][numberOfPoints[pointSetID]-1]<<endl<<P[pointSetID][0]<<endl;		
		current_angle+=angle[0]+360-angle[numberOfPoints[pointSetID]-1];
	}
	else
		oo<<"0"<<endl<<P[pointSetID][numberOfPoints[pointSetID]-1]<<endl<<P[pointSetID][0]<<endl;		


	for(int i=1;i<numberOfPoints[pointSetID]+1;i++)
    {
        ray[i] = ray[i - 1] - numberOfPoints[pointSetID] + 2*total[i-1]+1;

		if(ray[i]>=1.0/8.0*numberOfPoints[pointSetID]*numberOfPoints[pointSetID])
		{
			if(i==numberOfPoints[pointSetID])
				oo<<"1"<<endl<<P[pointSetID][i-1]<<endl<<P[pointSetID][0]<<endl;		
			else
				oo<<"1"<<endl<<P[pointSetID][i-1]<<endl<<P[pointSetID][i]<<endl;		
			current_angle+=angle[i]-angle[i-1];
		}
		else
		{
			if(i==numberOfPoints[pointSetID])
				oo<<"0"<<endl<<P[pointSetID][i-1]<<endl<<P[pointSetID][0]<<endl;		
			else
				oo<<"0"<<endl<<P[pointSetID][i-1]<<endl<<P[pointSetID][i]<<endl;		
			if(current_angle > largest_angle)
			{
				largest_angle=current_angle;
				current_angle=0;			
			
			}
		}


		if (minDepth > ray[i])
		{
            minDepth = ray[i];            
			did2=i;
		}
    }
	oo.close();
    return minDepth;
}
ostream& operator <<(ostream &os,const MyPoint &obj)
{
      //os<<"("<<obj.x<<", "<<obj.x<<")";
	os<<obj.x<<endl<<obj.y;
      return os;
}


bool operator<(const MyPoint &obj,const MyPoint &obj1)
{
	return obj.angle<obj1.angle;	 
}
